package com.netwit.shiro.jwt.controller;

import com.netwit.shiro.jwt.JWToken;
import com.netwit.shiro.jwt.JwtConfig;
import com.netwit.shiro.jwt.redis.RedisUtil;
import com.netwit.shiro.jwt.token.service.SecretService;
import com.netwit.shiro.jwt.util.JWTUtil;
import com.netwit.shiro.jwt.util.PasswordHelper;
import com.netwit.shiro.jwt.util.ResponseBean;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;

@Slf4j
@RestController
public class TokenController {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private JwtConfig jwtConfig;

    @Autowired
    private SecretService secretService;

    @Autowired
    private PasswordHelper passwordHelper;

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public ResponseBean login(@RequestParam("username") String username, @RequestParam("password") String password, HttpServletRequest request) {
        try{
            String newPassword = passwordHelper.encryptPassword(username, password);
            //JWToken token = new JWToken(JWTUtil.sign(username, newPassword, 600000));
            JWToken token = new JWToken(JWTUtil.accessToken(username, newPassword));
            SecurityUtils.getSubject().login(token);
            return new ResponseBean(200, "Login success", token.getPrincipal());
        } catch (Exception e) {
            String data = username + " 用户不存在或密码错误";
            return new ResponseBean(500, "Login failure", data);
            //throw new Exception("username or password is not correct.");
        }
    }

    @RequestMapping(value = "/401", method = RequestMethod.GET)
    public ResponseBean send401() {
        return new ResponseBean(401, "您需要登录或相关操作权限！", "");
    }

    @ResponseBody
    @GetMapping("/tokentest")
    public ResponseBean test(ServletRequest request, ServletResponse response){
        String token = ((HttpServletRequest)request).getHeader("Authorization");
        return new ResponseBean(200, "testtesttest", token);
    }

    @GetMapping("/refreshToken")
    public ResponseBean refreshToken(ServletRequest request){
        try{
            log.info("token-service ---------- refreshToken");
            log.info(jwtConfig.getExp());
            HttpServletRequest req = (HttpServletRequest)request;
            String refreshToken = req.getHeader("token");
            log.info("token:" + refreshToken);
            String accessToken  = req.getHeader("accessToken");
            RedisUtil.set(redisTemplate, accessToken, accessToken, new Long(jwtConfig.getExp()));
            RedisUtil.set(redisTemplate, refreshToken, refreshToken, new Long(jwtConfig.getExp()));

            String userId = JWTUtil.getUserId(refreshToken);
            String secret = secretService.secret(userId);
            accessToken  = JWTUtil.accessToken(userId, secret);
            refreshToken = JWTUtil.refreshToken(userId, secret);
            RedisUtil.set(redisTemplate, accessToken, accessToken, new Long(jwtConfig.getAccessToken()));
            RedisUtil.set(redisTemplate, refreshToken, refreshToken, new Long(jwtConfig.getRefreshToken()));

            return new ResponseBean(200, "success", accessToken + "__" + refreshToken);
        } catch (NumberFormatException nfe) {
            log.info(nfe.getMessage());
            return new ResponseBean(200, "error", null);
        }
    }

    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    @ResponseBody
    public ResponseBean logout(@RequestParam("accessToken")String accessToken, @RequestParam("refreshToken")String refreshToken){
        RedisUtil.set(redisTemplate, accessToken, accessToken, new Long(jwtConfig.getExp()));
        RedisUtil.set(redisTemplate, refreshToken, refreshToken, new Long(jwtConfig.getExp()));
        return new ResponseBean(200, "success", "");
    }

}
